﻿using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using AForge.Video.VFW;
using AIthin.Model.Body;
using AIthin.Model;

namespace AIthin.Controls
{
    public partial class RealityControl : UserControl
    {
        /// <summary>
        /// Abgebildete Reality 
        /// </summary>
        Reality R;
        /// <summary>
        /// Bitmap die Abbildet Reality in den Zeitschritt
        /// </summary>
        Bitmap bmRealitySnap;
        StructViewControl ViewControl;
        String OutStream = ".\\default.avi";
        public String WorkingPath { get; set; }
        /// <summary>
        /// erstellt neues Instanz vom AVI Datei mit "XVID" Komprimierung
        /// </summary>
        AVIWriter writer = new AVIWriter();
        /// <summary>
        /// definition for the event 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void TickComputed(object sender, string e);
        /// <summary>
        /// send event when one tick will be computed
        /// </summary>
        public event TickComputed netTickComputed;
        /// <summary>
        /// Konstruktor
        /// </summary>
        public RealityControl()
        {
            InitializeComponent();
            this.SetStyle(0
                                | ControlStyles.OptimizedDoubleBuffer //DoubleBuffer
                                | ControlStyles.UserPaint
                                | ControlStyles.AllPaintingInWmPaint
                                , true);

            this.UpdateStyles();

            R = new Pattern(64);
 
            bmRealitySnap = new Bitmap(2 * R.Size, R.Size, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            timerReality.Start();
        }
        private void timerReality_Tick(object sender, EventArgs e)
        {

        }
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.DrawImage(bmRealitySnap, 10, 10);
        }
        private void buttonRun_Click(object sender, EventArgs e)
        {

            comboBoxSize.Enabled = false;
            textBoxFramesCount.Enabled = false;
            buttonRun.Enabled = false;
            comboBoxModel.Enabled = false;


            //TODO Abarbeiten Datei freigabe
            writer.Close();
            // create new AVI file and open it
            saveLernFileDialog.InitialDirectory = WorkingPath;
            saveLernFileDialog.ShowDialog();

            bmRealitySnap.Dispose();

            int s = System.Convert.ToInt16(comboBoxSize.SelectedItem);

            try
            {
                switch (comboBoxModel.SelectedItem.ToString())
                {
                    case "Pattern": R = new Pattern(s);
                        break;
                    case "Squash": R = new Squash(s);
                        break;
                    default:
                        break;
                }
            }
            catch (Exception)
            {
                R = new Pattern(s);
                MessageBox.Show("Pattern set");
            }

            bmRealitySnap = new Bitmap(2 * R.Size, R.Size, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            int Frames = int.Parse(textBoxFramesCount.Text);

            try
            {
                OutStream = saveLernFileDialog.FileName;
                // create new AVI file and open it
                writer.Open(OutStream, R.Size * 2, R.Size);
            }
            catch (Exception)
            {
                MessageBox.Show("Cancelled. Cannt create output File");
                return;
                //          throw;
            }

            long Time = 0;

            // Main loop!
            while (Time < Frames + 1)
            {
                //Show Time
                textBoxFramesCount.Text = Time++.ToString();

                // Realitätsbewegung pro einen Tick
                //draw matrix vor input
                R.Moving();

                // erstellt neues Schreiben in Bild
                Graphics g = Graphics.FromImage(bmRealitySnap);
                R.Draw(g);

                // Aufnehmen
                if (checkBoxAVI.Checked)
                {
                    // den Control Neue zeichnung veranlassen
                    this.Invalidate();
                    writer.AddFrame(bmRealitySnap);
                }
                //let another Apps to work
                Application.DoEvents();
            }

            writer.Close();
  
            /*
                        DataTable tableLearnFile = learnFileTableAdapter1.GetData();
                        //TODO change to relative path 
                        learnFileTableAdapter1.Insert(tableLearnFile.Rows.Count + 1, OutStream, null, GetLearnFile(OutStream));
                        //TODO Think about two DataSets in Neurotic and Model, how about just one from Neurotic
                        learnFileTableAdapter1.Update(researchDBExpressDataSet1.LearnFile);
            */

            this.ParentForm.Close();
            MessageBox.Show("Learn Pattern " + OutStream + " created");
        }
        /// <summary>
        /// Main loop for reality moving >  
        /// </summary>
        /// <param name="g"> Graphics for reality drawing </param>
        private void btnStop_Click(object sender, EventArgs e)
        {
            this.ParentForm.Close();
        }
        public static byte[] GetLearnFile(string filePath)
        {
            FileStream stream = new FileStream(
                filePath, FileMode.Open, FileAccess.Read);
            BinaryReader reader = new BinaryReader(stream);

            byte[] file = reader.ReadBytes((int)stream.Length);

            reader.Close();
            stream.Close();

            return file;
        }
    }
}
